Skip to content

Conversation

icculus
Copy link
Collaborator

@icculus icculus commented Nov 21, 2024

This is an attempt to restore the ATOMIC support to the kmsdrm backend.

This was done by merging @vanfanel's final atomic work from SDL2 into the latest from SDL3. This wasn't a trivial effort, as a lot had changed in both kmsdrm specifically and SDL3 generally, so I expect there are issues to resolve in this PR still. It's at the "it compiles" stage; I'll be trying it on a Raspberry Pi 5 soon and fixing obvious issues that pop up.

There isn't a separate atomic and non-atomic version of the kmsdrm backend in this PR; it's now one codebase that will decide to use the atomic features if it can set the DRM_CLIENT_CAP_ATOMIC and DRM_CLIENT_CAP_UNIVERSAL_PLANES client capabilities. If not, it'll use the "legacy" codepaths. Before merging, we should probably add an SDL hint to let people turn off atomic support even if the system would otherwise support it, as a failsafe.

Note a few FIXMEs in this PR; these were pieces I couldn't decide how to correctly adapt, but I made a reasonable attempt anyhow.

Reference Issue #4984.

@icculus icculus added this to the 3.2.0 milestone Nov 21, 2024
@icculus
Copy link
Collaborator Author

icculus commented Dec 11, 2024

I'm not sure we should get into the business of promising to crash the entire process if something goes wrong, by adding assert_always to this.

@slouken
Copy link
Collaborator

slouken commented Dec 11, 2024

I'm not sure we should get into the business of promising to crash the entire process if something goes wrong, by adding assert_always to this.

Agreed. Gamers get very unhappy if they lose several hours progress without getting a chance to save. :)

@icculus
Copy link
Collaborator Author

icculus commented Dec 16, 2024

Tried this out on a raspberry pi, and it mostly works. Here's the current TODO list:

  • It crashes because it does this in several places...

    SDL_DisplayData *dispdata = (SDL_DisplayData *)SDL_GetDisplayDriverData(0);

    ...and this results in a NULL dispdata. I assume this function changed from an index to an instance ID, and hardcoding a 1 instead of a zero makes this work, since that's the instance ID that I've got. But I assume this also comes from a time where you'd only have one display in the kmsdrm backend, so this probably needs a bit of a refactor in any case to not have a hardcoded value.

  • Running things like testsprite and testaudio are only rendering a tiny window to maybe a quarter of the screen, in the top right. Something failed to scale? Something failed to change resolutions? I'm not sure. This definitely takes the whole television screen in main, so it's a regression.

  • The mouse cursor on my 1080p TV is microscopic. Might be that it was intended to scale and didn't?

These are obviously important issues to resolve, but I was surprised that it was otherwise rendering stuff on the (almost) first attempt. More work to be done still, though.

@slouken
Copy link
Collaborator

slouken commented Dec 16, 2024

Tried this out on a raspberry pi, and it mostly works. Here's the current TODO list:

  • It crashes because it does this in several places...
    SDL_DisplayData *dispdata = (SDL_DisplayData *)SDL_GetDisplayDriverData(0);

As you noted, we probably want to get the correct display data. If we have a window, you can use SDL_GetDisplayDriverDataForWindow(). Otherwise if you really want the first display, you can use SDL_GetDisplayDriverData(SDL_GetPrimaryDisplay()).

@ccawley2011
Copy link
Contributor

ccawley2011 commented Dec 27, 2024

  • Running things like testsprite and testaudio are only rendering a tiny window to maybe a quarter of the screen, in the top right. Something failed to scale? Something failed to change resolutions? I'm not sure. This definitely takes the whole television screen in main, so it's a regression.

Setting VIDEO_DEVICE_CAPS_FULLSCREEN_ONLY for the kmsdrm backend might help here, but that does assume that it doesn't need to support multiple windows on a single display.

@slouken slouken modified the milestones: 3.2.0, 3.4.0 Jan 10, 2025
@slouken slouken added the early in milestone This change should be made early in the milestone for additional testing label Jan 10, 2025
@icculus icculus force-pushed the sdl3-restore-atomic-kmsdrm branch from 9dc6c6e to ed93dde Compare September 11, 2025 14:38
@icculus
Copy link
Collaborator Author

icculus commented Sep 11, 2025

Rebased this to remove conflicts; going to try to get this finished, finally.

@icculus
Copy link
Collaborator Author

icculus commented Oct 16, 2025

Latest pushes fix up the display data problems, and add a hint to use as an escape hatch to turn off the atomic support.

This now works pretty well on my laptop!

I need to test this on a television to see if the scaling issue is still a thing. I'll plug in an HDMI cable tonight and see what happens.

@icculus icculus marked this pull request as ready for review October 17, 2025 20:11
@icculus
Copy link
Collaborator Author

icculus commented Oct 17, 2025

Okay, scaling is fixed (it was actually that the merged code didn't change the vidmode at all in the atomic paths, due to a behavior that changed at some point in SDL).

As far as I know, this is able to be merged now. It works here on both my laptop screen and an external HDMI monitor on the same device, both with and without atomic support.

@slouken
Copy link
Collaborator

slouken commented Oct 17, 2025

Have you tested OpenGL as well as Vulkan? Have you verified #4984 is fixed?

@icculus
Copy link
Collaborator Author

icculus commented Oct 17, 2025

Have you tested OpenGL as well as Vulkan?

OpenGL definitely works; I can't get Vulkan to work even without this PR for some reason. I'll see if a Raspberry Pi will do it, perhaps.

@icculus
Copy link
Collaborator Author

icculus commented Oct 17, 2025

Have you tested OpenGL as well as Vulkan? Have you verified #4984 is fixed?

I haven't yet, but the goal here was just to get the thing merged and working. I'll test this, too.

@icculus icculus force-pushed the sdl3-restore-atomic-kmsdrm branch from 33869a8 to 7713ecb Compare October 18, 2025 18:00
@icculus
Copy link
Collaborator Author

icculus commented Oct 18, 2025

Okay, this needs a little more testing to verify Vulkan support and mouse input stuff, but the basic concerns are all resolved now.

@icculus icculus force-pushed the sdl3-restore-atomic-kmsdrm branch from 68748a5 to ab674ee Compare October 18, 2025 19:01
@icculus
Copy link
Collaborator Author

icculus commented Oct 19, 2025

Okay, so, some interesting findings:

  • Vulkan doesn't work with our kmsdrm backend, with either the atomic or non-atomic paths through this PR, or what's currently in main. It fails here:

SDL_SetError("Vulkan can't find any displays.");

Which is to say it finds GPUs, but doesn't find displays attached to them...which it should, I assume. I don't know why it doesn't.

I built this thing and ran it from the console, though:

https://github.com/nyorain/kms-vulkan

And it drew just fine through Vulkan...it doesn't make a call to vkGetPhysicalDeviceDisplayPropertiesKHR, so it's possible the solution is to just dump this bit of code altogether from our backend (why are we having Vulkan enumerate displays? Didn't we just do this anyhow with our own kmsdrm code?), but I haven't dug in further yet.

But we shouldn't hold up this PR any further, at least for this specific issue.

Also:

  • Main's kmsdrm backend is totally broken on a Raspberry Pi 5, but the atomic version in this PR works.

The non-atomic code path just puts garbage on the screen on a Pi5 for whatever reasons. The atomic path works just fine with testsprite, etc, though.

Finally:

I'm just sitting here moving the mouse constantly during testsprite, and it doesn't seem to slow down at all (and the FPS reports every five seconds are consistent between runs where I leave it alone and runs where I don't).

The atomic backend appears to be syncing to vblank by default (steady 60 fps), whereas non-atomic doesn't, which is either normal or something we should fix...but both the atomic and non-atomic versions in this PR, and main, don't suffer any framerate loss from mouse movement.

So I might need a better test case than testsprite. @slouken, did you have something specific that was taking a hit on mouse movement we can try with this PR?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

early in milestone This change should be made early in the milestone for additional testing

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants